package com.gitee.vueantd.upload.rest;

import com.gitee.vueantd.upload.domain.UploadChunk;
import com.gitee.vueantd.upload.repository.UploadChunkRepository;
import com.gitee.vueantd.upload.service.UploadService;
import com.gitee.vueantd.upload.service.dto.ChunkRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.persistence.criteria.Predicate;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @ClassName: UploadFileController
 * @Description: TODO
 * @Author: fuqiang zheng
 * @Date: 2021/4/30 9:37
 * @Version 1.0
 */
@Slf4j
@RestController
@RequestMapping("/api/upload")
public class UploadFileController {

  @Autowired
  private UploadService uploadService;

  @Autowired
  private UploadChunkRepository uploadChunkRepository;

  @GetMapping(value = "/chunk")
  public void chunk(HttpServletRequest request,
                    HttpServletResponse response) {
    try {
      ChunkRequest chunkRequest = new ChunkRequest(request);
      log.debug("enter check ={}", chunkRequest);
      Optional<UploadChunk> uploadChunkOptional = uploadChunkRepository
              .findOne(buildUploadChunkSpecification(chunkRequest));
      if (!uploadChunkOptional.isPresent()) {
        response.setStatus(HttpServletResponse.SC_NOT_FOUND);
      }
    } catch (Exception e) {
      log.error("{}", e);
      response.setStatus(HttpServletResponse.SC_NOT_FOUND);
    }
  }

  private Specification<UploadChunk> buildUploadChunkSpecification(ChunkRequest chunkRequest) {
    return (Specification<UploadChunk>) (root, criteriaQuery, criteriaBuilder) -> {
      List<Predicate> predicates = new ArrayList<>();
      predicates.add(criteriaBuilder.equal(root.get("chunkIndex"), chunkRequest.chunkIndex));
      predicates.add(criteriaBuilder.equal(root.get("chunkSize"), chunkRequest.chunkSize));
      predicates.add(criteriaBuilder.equal(root.get("fileSize"), chunkRequest.fileSize));
      predicates.add(criteriaBuilder.equal(root.get("fileHash"), chunkRequest.fileHash));
      predicates.add(criteriaBuilder.equal(root.get("fileType"), chunkRequest.fileType));
      predicates.add(criteriaBuilder.equal(root.get("nodeId"), chunkRequest.nodeId));
      return criteriaBuilder.and(predicates.toArray(new Predicate[]{}));
    };
  }

  @PostMapping(value = "/chunk")
  public void upload(HttpServletRequest request) throws Exception {
    uploadService.upload(request);
  }

}